﻿using Library.Collections;
using Library.Collections.Generic;
using Library.Logic.Constraints;
using System.Linq.Expressions;
using TRULE = System.Linq.Expressions.Expression<System.Func<System.Linq.IQueryable<System.Linq.Expressions.Expression>, System.Collections.Generic.IEnumerable<System.Collections.Generic.IEnumerable<System.Linq.Expressions.Expression>>>>;
using TEXPRESSION = System.Linq.Expressions.Expression;
using TPARAMETEREXPRESSION = System.Linq.Expressions.ParameterExpression;

namespace Library.Reflection
{
    public interface IGroup<out T> : System.Collections.Generic.IEnumerable<T>, ICountable
    {
        T Bind(object[] arguments);
    }

    public interface IGeneratorGroup<out TGenerator, out T> : IGroup<TGenerator>
        where TGenerator : IGenerator<TGenerator, T>
        where T : IPolymorphic<TGenerator, T>
    {
        T Generate(object[] arguments);
    }

    public interface IGenerator<out TGenerator, out T> : IHasGeneratorParameters, IHasPreconditionsReasonGenerator
        where TGenerator : IGenerator<TGenerator, T>
        where T : IPolymorphic<TGenerator, T>
    {
        IGeneratorGroup<TGenerator, T> GeneratorGroup { get; }

        T Generate(object[] parameters);
    }

    public interface IPolymorphic<out TGenerator, out T>
        where TGenerator : IGenerator<TGenerator, T>
        where T : IPolymorphic<TGenerator, T>
    {
        TGenerator Generator { get; }
        IVectorReadOnly<object> PolymorphicParameters { get; }
    }

    public interface IPolymorphic<out T> : IGenerator<T, T>, IPolymorphic<T, T>
        where T : IGenerator<T, T>, IPolymorphic<T, T>
    {
        bool IsGenerator { get; }
    }
}